﻿using System;
using log4net;
using log4net.Appender;
using System.IO;

namespace VO.Logging
{
    public class LoggerManager : ILogger
    {
        private static object syncLock = new object();
        private static ILogger instance;
        /// <summary>
        /// Gets the current.
        /// </summary>
        /// <value>The current.</value>
        public static ILogger Current
        {
            // Support multithreaded applications through 
            // 'Double checked locking' pattern which (once 
            // the instance exists) avoids locking each 
            // time the method is invoked 
            get
            {
                if (instance == null)
                {
                    lock (syncLock)
                    {
                        if (instance == null)
                        {
                            instance = new LoggerManager();
                        }
                    }
                }

                return instance;

            }
        }


        /// <summary>
        /// Initializes a new instance of the <see cref="LoggerManager"/> class.
        /// </summary>
        private LoggerManager()
        {
            log4net.Config.XmlConfigurator.Configure();
        }

        #region ILogger Members

        // log message only
        /// <summary>
        /// Debugs the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        public void Debug(Type type, object message)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Debug(message);
        }

        /// <summary>
        /// Infoes the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        public void Info(Type type, object message)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Debug(message);
        }

        /// <summary>
        /// Warns the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        public void Warn(Type type, object message)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Warn(message);
        }

        /// <summary>
        /// Errors the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        public void Error(Type type, object message)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Error(message);
        }

        /// <summary>
        /// Fatals the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        public void Fatal(Type type, object message)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Fatal(message);
        }
        // - log message and exception

        /// <summary>
        /// Debugs the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        /// <param name="ex">The ex.</param>
        public void Debug(Type type, object message, Exception ex)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Debug(message, ex);
        }

        /// <summary>
        /// Infoes the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        /// <param name="ex">The ex.</param>
        public void Info(Type type, object message, Exception ex)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Info(message, ex);
        }

        /// <summary>
        /// Warns the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        /// <param name="ex">The ex.</param>
        public void Warn(Type type, object message, Exception ex)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Warn(message, ex);
        }

        /// <summary>
        /// Errors the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        /// <param name="ex">The ex.</param>
        public void Error(Type type, object message, Exception ex)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Error(message, ex);
        }

        /// <summary>
        /// Fatals the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="message">The message.</param>
        /// <param name="ex">The ex.</param>
        public void Fatal(Type type, object message, Exception ex)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.Fatal(message, ex);
        }
        //-- logger formated

        /// <summary>
        /// Debugs the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void DebugFormat(Type type, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.DebugFormat(format, args);
        }

        /// <summary>
        /// Infoes the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void InfoFormat(Type type, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.InfoFormat(format, args);
        }

        /// <summary>
        /// Warns the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void WarnFormat(Type type, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.WarnFormat(format, args);
        }

        /// <summary>
        /// Errors the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void ErrorFormat(Type type, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.ErrorFormat(format, args);
        }

        /// <summary>
        /// Fatals the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void FatalFormat(Type type, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.FatalFormat(format, args);
        }

        /// <summary>
        /// Debugs the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="provider">The provider.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void DebugFormat(Type type, IFormatProvider provider, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.DebugFormat(provider, format, args);
        }

        /// <summary>
        /// Infoes the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="provider">The provider.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void InfoFormat(Type type, IFormatProvider provider, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
        }

        /// <summary>
        /// Warns the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="provider">The provider.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void WarnFormat(Type type, IFormatProvider provider, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.WarnFormat(provider, format, args);
        }

        /// <summary>
        /// Errors the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="provider">The provider.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void ErrorFormat(Type type, IFormatProvider provider, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.ErrorFormat(provider, format, args);
        }

        /// <summary>
        /// Fatals the format.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="provider">The provider.</param>
        /// <param name="format">The format.</param>
        /// <param name="args">The args.</param>
        public void FatalFormat(Type type, IFormatProvider provider, string format, params object[] args)
        {
            ILog logger = LogManager.GetLogger(type);
            logger.FatalFormat(provider, format, args);
        }

        /// <summary>
        /// Get the file for info log
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public string GetInfoFile(Type type)
        {
            ILog logger = LogManager.GetLogger(type);
            foreach (IAppender appn in logger.Logger.Repository.GetAppenders())
            {
                if (appn is FileAppender)
                {
                    FileAppender fileappn = appn as FileAppender;
                    if (fileappn.Name == "InfoLogAppender")
                    {
                        return Path.Combine(Path.GetDirectoryName(fileappn.File), "SQL_DC_TRACE.txt");
                    }
                }
            }
            return string.Empty;
        }
        #endregion
    }
}
